#include <iostream>
#include <new>

template<class T>
class NewHandlerSupport{
public:
	static new_handler set_new_handler(new_handler p);
	static void* operator new(size_t size);
private:
	static new_handler currentHandler;
};

template<class T>
new_handler NewHandlerSupport<T>::set_new_handler(new_handler p)
{
	new_handler oldHandler = currentHandler;
	currentHandler = p;
	return oldHandler;
}

template<class T>
void* NewHandlerSupport<T>::operator new(size_t size)
{
	new_handler globalHandler = std::set_new_handler(currentHandler);
	void* memory;
	try {
		memory = ::operator new(1000000 * size);
	} catch(std::bad_alloc&){
		std::set_new_handler(globalHandler);
		throw;
	}
	std::set_new_handler(globalHandler);
	return memory;
}

template<class T>
new_handler NewHandlerSupport<T>::currentHandler = 0;

class Rational : public NewHandlerSupport<Rational>{
public:
	Rational(int numerator = 0, int denominator = 1):n(numerator), d(denominator){};

private:
	int n, d;
	friend std::ostream& operator<<(std::ostream& s, const Rational& r);
};

std::ostream& operator<<(std::ostream& s, const Rational& r)
{
	s << r.n << '/' << r.d ;
	return s;
}

void noMoreMemory()
{
	std::cerr << "Unable to satisfy request for memory for RATIONAL\n";
	abort();
}

int run()
{
	Rational a(4,5);
	std::cout << a;
	std::string* stringArray = new std::string[100];
	delete [] stringArray;
	typedef std::string AddressLines[4];	
	std::string* pal = new AddressLines;
	pal[3] = "Hello";
	delete [] pal;
	std::set_new_handler(noMoreMemory);
	int i = 0;
	//while (i<10000000000) {
	//	std::string* s = new std::string[10000000];
	//	++i;
	//}
	/*class specific new handler
	NewHandlerSupport<Rational>::set_new_handler(noMoreMemory);
	while (i<10000000000000) {
		new Rational(10000000000000000000);
		++i;
	}*/
 	return 0;
}
 